/*
 * @Date         : 2022-06-15 14:27:18
 * @LastEditTime: 2024-07-16 09:27:05
 * @LastEditors: Liu 2689810937@qq.com
 * @Description  :  显示屏通讯头文件，包含迪文屏串口协议
 * @FilePath     : \template\btn_scan\Protocol.h
 * @FileLog      :
 */
#ifndef PROTOCOL_H
#define PROTOCOL_H

#include "pro_config.h"
#include "uart2.h"
#include "string.h"
#include "btn_scan.h"

//类型重定义
/* ####################################结构体声明################################# */
/* 读写寄存器结构体 */
typedef struct
{
    u16 real_time_pressure;                      /* 实时压力 */
    u16 set_pressure;                            /* 设置压力 */
    u16 set_flow_rate;                           /* 设置流量 */
    u16 unit_identification;                     /* 单位标识 */
    u16 save_button;                             /* 保存按键 */
    u16 ready_flag;                              /* 准备标志 */
    u16 reserve[10];                             /* 保留10 */
    u16 calibration_pressure_true_value[10];     /* 标定压力真实值 */
    u16 calibration_pressure_measured_value[10]; /* 标定压力测量值 */
    u16 calibration_flow_value[10];              /* 标定流量值 */
    u16 calibration_rotation_speed_value[10];    /* 标定转速值 */
    u16 reserved[8];                             /* 预留 */
    u16 calibration_set_pressure;                /* 标定压力 */
    u16 calibration_set_flow;                    /* 注意：这里我添加了_again以避免命名冲突 */
    u16 calibration_pressure_switch;             /* 标定压力开关 */
    u16 adcnow;                                  /* ADCnow（可能是指当前ADC值） */
    u16 rotation_speed_setting;                  /* 转速设置 */
    u16 rotation_speed_switch;                   /* 转速开关 */
    u16 kp;                                      /* KP（PID控制中的比例增益） */
    u16 ki;                                      /* KI（PID控制中的积分增益） */
    u16 kd;                                      /* KD（PID控制中的微分增益） */

    u16 reserver1[100];
} rwStruct;
/* 只读结构体 */
typedef struct
{
    u16 reserver;
} rStruct;
/* 只写寄存器结构体 */
typedef struct
{
    u16 reserver;

} wStruct;

typedef struct
{
    wStruct regW;      /* 只写寄存器组 */
    rwStruct regRW;    /* 读写寄存器组 */
    u16 crc16;         /* crc16，用于保存参数时校验 */
    rStruct regR;      /* 只读寄存器组 */
    u16 regRSIZE;      /* 只读寄存器组大小 */
    u16 regWSIZE;      /* 只写寄存器组大小 */
    u16 regRWSIZE;     /* 读写寄存器组大小 */
    u16 flashSaveSize; /* 要保存的数据大小 */
} regStruct;
extern regStruct regSt;

/* 协议结构体 */
typedef struct
{
    u8 head[3]; /* 帧头 */
    struct addr
    {
        u8 srcAddr : 4; /* 源地址 */
        u8 desAddr : 4; /* 目标地址 */
    } addrSt;
    struct cmd
    {
        u8 cmdCode : 4;    /* 功能码 0x3：读寄存器 0x6：写寄存器 */
        u8 cmdErrCode : 3; /* 命令应答码 0-命令帧正确；1- 校验错误；2-数据长度有误；
                             3- 用户寄存器地址无效；4-目标设备目前状态无法响应命令；5-7：其他错误 */
        u8 cmdAck : 1;     /* 命令方向 0：下发 1：应答 */
    } cmdSt;
    u8 dataAreaNum;
    u16 dataAreaLen;
    u8 dataArea[DATA_AREA_SIZE];
    u16 crc16;
} protocolStruct;
extern protocolStruct protocolSt;

typedef struct
{
    u16 regAddr[10];
    u8 regNum[10];
} addrAndNumStruct;
extern addrAndNumStruct addrAndNumSt;
/* ####################################宏定义################################# */
#define PROTOCOL_READ 0x03
#define PROTOCOL_WRITE 0x06

#define ERR_NONE 0     /* 无错误 */
#define ERR_CRC 1      /* 校验错误 */
#define ERR_LEN 2      /* 数据长度错误 */
#define ERR_REG 3      /* 用户寄存器地址无效 */
#define ERR_BUSY 4     /* 设备繁忙 */
#define ERR_CODE 5     /* 功能码错误 */
#define ERR_ADDR_CMD 6 /* 命令或者地址错误 */

#define LCD_ADDR 0     /* 屏幕地址 */
#define MAIN_ADDR 1    /* 主板地址 */
#define RFID_ADDR 2    /* RFID地址 */
#define POWER_ADDR 3   /* 功率回采板地址 */
#define DRIVER1_ADDR 4 /* 驱动板1地址 */
#define DRIVER2_ADDR 5 /* 驱动板2地址 */
#define GPRS_ADDR 6    /* GPRS地址 */
#define PC_ADDR 7      /* PC上位机*/
/* ####################################函数声明################################# */
#define RESERVER_PTR 0x0000, 0x0
#define PTR_NUM_1 RESERVER_PTR, RESERVER_PTR, RESERVER_PTR, RESERVER_PTR, RESERVER_PTR, \
                  RESERVER_PTR, RESERVER_PTR, RESERVER_PTR, RESERVER_PTR, 1
#define PTR_NUM_2 RESERVER_PTR, RESERVER_PTR, RESERVER_PTR, RESERVER_PTR, RESERVER_PTR, \
                  RESERVER_PTR, RESERVER_PTR, RESERVER_PTR, 2
#define PTR_NUM_3 RESERVER_PTR, RESERVER_PTR, RESERVER_PTR, RESERVER_PTR, RESERVER_PTR, \
                  RESERVER_PTR, RESERVER_PTR, 3
#define PTR_NUM_4 RESERVER_PTR, RESERVER_PTR, RESERVER_PTR, RESERVER_PTR, RESERVER_PTR, \
                  RESERVER_PTR, 4
#define PTR_NUM_5 RESERVER_PTR, RESERVER_PTR, RESERVER_PTR, RESERVER_PTR, RESERVER_PTR, 5
#define PTR_NUM_6 RESERVER_PTR, RESERVER_PTR, RESERVER_PTR, RESERVER_PTR, 6
#define PTR_NUM_7 RESERVER_PTR, RESERVER_PTR, RESERVER_PTR, 7
#define PTR_NUM_8 RESERVER_PTR, RESERVER_PTR, 8
#define PTR_NUM_9 RESERVER_PTR, 9
#define PTR_NUM_10 10
u8 crc_check(u8 *in_buf, u16 in_buf_len);
u16 crc16(u8 *Pushdata, u16 length);
u8 protocol_recv_deal(void);
void serial_recv_response(u8 errCode);
void protocol_init(void);
void user_system_init(void);
u8 protocol_writeCmdDataArea_deal(void);
u8 protocol_readCmdDataArea_deal(void);
u16 read_reg_value(u16 regAddr);
u8 protocol_readOnlyCmdDataArea_deal(void);
void protocol_send_reg(u8 mcode,
                       u16 regAddr0, u8 regNum0,
                       u16 regAddr1, u8 regNum1,
                       u16 regAddr2, u8 regNum2,
                       u16 regAddr3, u8 regNum3,
                       u16 regAddr4, u8 regNum4,
                       u16 regAddr5, u8 regNum5,
                       u16 regAddr6, u8 regNum6,
                       u16 regAddr7, u8 regNum7,
                       u16 regAddr8, u8 regNum8,
                       u16 regAddr9, u8 regNum9,
                       u8 ptrNum);
void protocol_send_RFID(u8 mcode,
                        u16 regAddr0, u8 regNum0,
                        u16 regAddr1, u8 regNum1,
                        u16 regAddr2, u8 regNum2,
                        u16 regAddr3, u8 regNum3,
                        u16 regAddr4, u8 regNum4,
                        u16 regAddr5, u8 regNum5,
                        u16 regAddr6, u8 regNum6,
                        u16 regAddr7, u8 regNum7,
                        u16 regAddr8, u8 regNum8,
                        u16 regAddr9, u8 regNum9,
                        u8 ptrNum);
void protocol_thread(void);

#endif
